package com.clei.Y2023.M09.D18;

import com.clei.utils.FileUtil;
import com.clei.utils.PrintUtil;
import com.clei.utils.io.ArrayDataContainer;
import com.clei.utils.io.DataHandler;
import com.clei.utils.io.ScheduleConfig;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * DataMap 使用DataHandler的升级版
 *
 * @author Y
 * @date 2023-09-18
 **/
public class NewDataMap {

    public static void main(String[] args) {
        // 初始化处理器
        Consumer<List<String>> dataConsumer = data -> {
            PrintUtil.log("消费数据数： {}", data.size());
            FileUtil.writeTxt("E:\\workTemp\\dataMap.txt", data, true);
        };
        ScheduleConfig scheduleConfig = new ScheduleConfig(1, 1, TimeUnit.SECONDS);
        DataHandler<String> dataHandler = new DataHandler<>(new ArrayDataContainer<>(200), dataConsumer, scheduleConfig);

        // 数据访问线程池
        ThreadPoolExecutor dataProducerExecutor = new ThreadPoolExecutor(
                4,
                9,
                30,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100000),
                new ThreadPoolExecutor.CallerRunsPolicy());
        // 控制时间的线程
        Thread timers = new Thread(() -> {
            try {
                // 10秒后停止
                TimeUnit.SECONDS.sleep(10);
                PrintUtil.log("shutdownNow");
                dataProducerExecutor.shutdownNow();
                dataHandler.stop(true);
            } catch (Exception e) {
                PrintUtil.log("timers sleep error ", e);
            }
        });
        // 放数据的线程
        Thread dataProducer = new Thread(() -> {
            Random random = new Random();
            try {
                for (int i = 0; !dataProducerExecutor.isTerminated(); i++) {
                    String key = String.valueOf(i);
                    dataProducerExecutor.execute(() -> {
                        dataHandler.put(key + ' ' + key);
                    });
                    TimeUnit.MILLISECONDS.sleep(random.nextInt(5));
                }
            } catch (Exception e) {
                PrintUtil.log("dataProducer error ", e);
            }
        });
        dataHandler.start();
        dataProducer.start();
        timers.start();
    }
}
